/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.util;

import com.comac.ins.common.core.exception.base.BaseException;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class UnitSymbolProcessor {

    // 字母斜体映射偏移量
    private static final int LOWERCASE_ITALIC_START = 0x1D44E; // 小写字母斜体起点
    private static final int UPPERCASE_ITALIC_START = 0x1D434; // 大写字母斜体起点

    // 数字和符号的上标 Unicode
    private static final char[] SUPERSCRIPTS = {
        '\u2070', '\u00B9', '\u00B2', '\u00B3', '\u2074',
        '\u2075', '\u2076', '\u2077', '\u2078', '\u2079'
    };
    private static final char SUPERSCRIPT_MINUS = '\u207B'; // 上标负号（−）
    private static final char TIMES = '\u00B7'; // 乘号

    public static void main(String[] args) {
        String input = "J*m^2/s^2";
        try {
            String result = processUnitExpression(input);
            System.out.println("最终转换结果：" + result);
        } catch (IllegalArgumentException e) {
            System.out.println("转换失败：" + e.getMessage());
        }
    }

    /**
     * 综合处理单位表达式
     * - 将单位符号转换为斜体
     * - 将上标表达式转换为上标字符
     *
     * @param input 输入的单位表达式
     * @return 转换后的表达式
     */
    public static String processUnitExpression(String input) {
        try {
            // 先处理括号和斜体字母
            String result = handleParentheses(input);
            result = convertToSuperscript(result);
            result = convertTimesSymbol(result); // 处理乘号
            result = convertToItalic(result);
            return result;
        } catch (Exception e) {
            throw new BaseException("单位不符合规则，单位：" + input + ", message:" + e.getMessage());
        }
    }

    private static String handleParentheses(String input) {
        Pattern pattern = Pattern.compile("\\(([^()]*)\\)");
        Matcher matcher = pattern.matcher(input);
        StringBuffer result = new StringBuffer();

        while (matcher.find()) {
            String innerContent = matcher.group(1);
            String processedContent = processUnitExpression(innerContent); // 递归处理括号内内容
            matcher.appendReplacement(result, "(" + processedContent + ")");
        }
        matcher.appendTail(result);
        return result.toString();
    }

    /**
     * 将单位符号中的字母转换为斜体
     *
     * @param input 输入字符串
     * @return 转换后的字符串
     */
    public static String convertToItalic(String input) {
        StringBuilder italicText = new StringBuilder();

        for (char c : input.toCharArray()) {
            if (c >= 'a' && c <= 'z') {
                italicText.append(Character.toChars(LOWERCASE_ITALIC_START + (c - 'a')));
            } else if (c >= 'A' && c <= 'Z') {
                italicText.append(Character.toChars(UPPERCASE_ITALIC_START + (c - 'A')));
            } else {
                italicText.append(c);
            }
        }
        return italicText.toString();
    }

    private static String convertToSuperscript(String input) {
        StringBuilder result = new StringBuilder();
        Pattern pattern = Pattern.compile("\\^(-?\\d+|\\(-?\\d+\\))");
        Matcher matcher = pattern.matcher(input);
        int lastEnd = 0;

        while (matcher.find()) {
            result.append(input, lastEnd, matcher.start());
            String power = matcher.group(1);
            result.append(formatPower(power));
            lastEnd = matcher.end();
        }
        result.append(input.substring(lastEnd));
        return result.toString();
    }

    private static String formatPower(String power) {

        // 去掉括号
        if (power.startsWith("(") && power.endsWith(")")) {
            power = power.substring(1, power.length() - 1);
        }

        StringBuilder formatted = new StringBuilder();
        // 处理幂次中的每个字符，数字和字母都转为上标
        for (char c : power.toCharArray()) {
            if (Character.isDigit(c)) {
                formatted.append(SUPERSCRIPTS[c - '0']); // 转换为上标数字
            } else if (Character.isLetter(c)) {
                formatted.append(convertToSuperscriptLetter(c)); // 转换为上标字母
            } else if (c == '-') {
                formatted.append(SUPERSCRIPT_MINUS); // 转换为上标负号
            } else {
                formatted.append(c); // 保留其他符号
            }
        }

        return formatted.toString();
    }

    /**
     * 将字母转换为上标字母
     * @param c 字母
     * @return 转换后的上标字母
     */
    private static char convertToSuperscriptLetter(char c) {
        // 大写字母上标范围
        if (c >= 'a' && c <= 'z') {
            return (char) (0x1D62 + (c - 'a')); // 小写字母上标
        } else if (c >= 'A' && c <= 'Z') {
            return (char) (0x1D2C + (c - 'A')); // 大写字母上标
        }
        return c; // 非字母返回原字符
    }

    /**
     * 将乘号（*）转换为上标乘号（·）
     * @param input 输入字符串
     * @return 转换后的字符串
     */
    private static String convertTimesSymbol(String input) {
        return input.replace('*', TIMES);
    }
}

